package tech.aistar.util;

import java.util.Arrays;

/**
 * 本类用来演示: 数组工具类
 *
 * @author: success
 * @date: 2022/7/19 3:13 下午
 */
public class ArrayUtil {
    public static void main(String[] args) {
        int[] arr = {1,2,3,4,5};

       // int[] temp = Arrays.copyOf(arr,arr.length+3);

        //System.out.println(Arrays.toString(temp));

        //int[] temp = delByTarget(arr,2);
        //int[] temp = delByIndex(arr,4);
        //int[] temp = shuffle(arr);

        System.out.println(Arrays.toString(addElement(arr,2,100)));

        //System.out.println(Arrays.toString(directSort(arr)));

        String[] sts = {"12","2","34","3"};
        Arrays.sort(sts);
        System.out.println(Arrays.toString(sts));
    }

    /**
     * 删除数组中指定的元素
     * @param arr
     * @param target
     * @return
     */
    public static int[] delByTarget(int[] arr,int target){
        //1. 判断参数的有效性
        if(null==arr || arr.length==0)
            return arr;

        //2. 确定新的数组的长度
        //新的数组中的元素肯定是不包含target
        int count = 0;//计数器

        //遍历原来的数组
        for (int i = 0; i < arr.length; i++) {
            if(arr[i] == target)
                count++;//统计出target出现的次数
        }

        //判断target在arr中是否出现过
        if(count==0)
            return arr;//说明target并没有出现

        //target出现了 - 确定新的数组的长度
        int[] temp = new int[arr.length-count];
        //定义一个下标计数器
        int pos = 0;
        for (int i = 0; i < arr.length; i++) {
            if(arr[i]!=target){
                temp[pos++] = arr[i];
            }
        }
        return temp;
    }

    /**
     * 根据下标进行删除 - 唯一性的
     * @param arr
     * @param pos
     * @return
     */
    public static int[] delByIndex(int[] arr,int pos){
        if(null==arr || arr.length==0)
            return arr;

        if(pos<0 || pos>arr.length-1)
            return arr;

        int[] temp = new int[arr.length-1];

        int index = 0;

        for (int i = 0; i < arr.length; i++) {
            if(i!=pos)
                temp[index++] = arr[i];
        }

        return temp;
    }

    /**
     * 随机打乱一个数组
     * @param arr
     * @return
     */
    public static int[] shuffle(int[] arr){
        if(null==arr || arr.length==0)
            return arr;

        int[] temp = new int[arr.length];

        int pos = 0;

        do{//前置循环
            //随机一个下标
            int index = (int) (Math.random()*arr.length);

            temp[pos++] = arr[index];

            //{};

            arr=delByIndex(arr,index);//根据下标删除

            if(arr.length==0)
                break;
        }while(true);

        return temp;
    }

    /**
     * 数组排重
     * @param arr
     * @return
     * @see delDoubleElement
     */
    @Deprecated
    public static int[] delDoubleElement(int[] arr){
        if(null==arr || arr.length==0)
            return arr;

        int[] temp = new int[arr.length];
        int pos = 0;

        //思路  arr = {};
        //     temp = {1,2,3,0,0,0}
        do{
            temp[pos++] = arr[0];

            arr = delByTarget(arr,arr[0]);

            if(arr.length==0)
                break;

        }while(true);

        return Arrays.copyOf(temp,pos);
    }

    public static int[] delDoubleElement2(int[] arr){
        if(null==arr || arr.length==0)
            return arr;

        boolean[] flag = new boolean[arr.length];
        //统一赋值
        Arrays.fill(flag,true);
        
        //思路
        //{1,2,3,3,3,2,1,2,4,3};
        //{T,T,T,F,F,F,F,F,T,F}

        for (int i = 0; i < arr.length; i++) {
            for (int j = i+1; j < arr.length; j++) {
                if(arr[i] == arr[j])
                    flag[j] = false;
            }
        }

        int count = 0;

        for (int i = 0; i < flag.length; i++) {
            if(flag[i])
                count++;
        }
        int[] temp = new int[count];
        int pos = 0;

        for (int i = 0; i < arr.length; i++) {
            if(flag[i])
                temp[pos++] = arr[i];
        }

        return temp;
    }

    public static int[] delDoubleElement3(int[] arr){
        if(null==arr || arr.length==0)
            return arr;
        //{1,2,3,3,3,2,1,2,4,3};

        //[1, 2, 3, 3, 2, 4]
        for (int i = 0; i < arr.length; i++) {
            for (int j = i+1; j < arr.length; j++) {
                if(arr[i] == arr[j]){
                    arr = delByIndex(arr,j);
                    j--;
                }
            }
        }
        return arr;
    }

    /**
     * 选择排序
     * 思想 - 从小到大 - 每一轮确定一个最小值,在最左边
     * 6 3 2 1 4
     * 3 6 2 1 4
     * 2 6 3 1 4
     * @param arr
     * @return
     */
    public static int[] sortSelect(int[] arr){
        //Arrays.sort(arr);
        if(null == arr|| arr.length==0)
            return  arr;
        for (int i = 0; i < arr.length; i++) {
            for (int j = i+1; j < arr.length; j++) {
                if(arr[i]>arr[j]){
                    arr[i] = arr[i]^arr[j];
                    arr[j] = arr[i]^arr[j];
                    arr[i] = arr[i]^arr[j];
                }
            }
        }
        return arr;
    }

    /**
     * 冒泡 - 俩俩进行交换
     * 从小到大 - 每次可以确定一个最大值,但是在最右边
     * 6 3 2 1 4
     * @param arr
     * @return
     */
    public static int[] sortBubble(int[] arr){
        for (int i = 0; i < arr.length; i++) {
            for (int j = 0; j < arr.length-i-1; j++) {
                if(arr[j]>arr[j+1]){
                    arr[j] = arr[j]^arr[j+1];
                    arr[j+1] = arr[j]^arr[j+1];
                    arr[j] = arr[j]^arr[j+1];
                }
            }
        }
        return arr;
    }

    //直接插入 - 号称最简单的排序方式
    //从第二个位置开始,保证前面的序列始终是一个有序的序列
    //3 1 2 5 3 2
    //1 3
    //1 2 3
    public static int[] directSort(int[] arr){

        for (int i = 1; i < arr.length; i++) {
            for (int j = i; j > 0 ; j--) {
                if(arr[j]<arr[j-1]){
                    arr[j] = arr[j]^arr[j-1];
                    arr[j-1] = arr[j]^arr[j-1];
                    arr[j] = arr[j]^arr[j-1];
                }
            }
        }
        return arr;
    }

    /**
     * arraycopy(Object src,  int  srcPos,
     *                                         Object dest, int destPos,
     *                                         int length);
     * 在数组指定的下标处插入一个值
     * @param arr
     * @param pos
     * @param target
     * @return
     */
    public static int[] addElement(int[] arr,int pos,int target){
        int[] temp = new int[arr.length+1];

        //pos = 3
        // 1 2 3 4 5
        System.arraycopy(arr,0,temp,0,pos);
        temp[pos] = target;
        System.arraycopy(arr,pos,temp,pos+1,arr.length-pos);

        return temp;
    }
}
